package org.jeecg.modules.demo.crm.controller;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.base.controller.JeecgController;
import org.jeecg.modules.demo.crm.dto.*;
import org.jeecg.modules.demo.crm.entity.*;
import org.jeecg.modules.demo.crm.mapper.*;
import org.jeecg.modules.demo.crm.service.ICCommonService;
import org.jeecg.modules.demo.crm.util.DateUtils;
import org.jeecg.modules.demo.crm.util.IndexUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * 首页
 */
@Api(tags="首页")
@RestController
@RequestMapping("/crm/index")
@Slf4j
public class IndexController extends JeecgController<CCommon, ICCommonService> {

   @Autowired
   private ICCommonService cCommonService;

   @Autowired
   private CProjectApplicationMapper cProjectApplicationMapper;

   @Autowired
   private CSubProjectMapper cSubProjectMapper;

   @Autowired
   private CContractorInfoMapper contractorInfoMapper;

   @Autowired
   private CContractMapper contractMapper;

   @Autowired
   private CCompanyInfoMapper companyInfoMapper;

   @Autowired
   private CPaymentRequestMapper paymentRequestMapper;

    @Autowired
    private CPaymentRecordMapper paymentRecordMapper;

    @Autowired
    private CProjectApplicationMapper projectApplicationMapper;

    @Autowired
    private CPaymentInvoiceMapper paymentInvoiceMapper;


    @Autowired
    private CInvoiceApplyMapper invoiceApplyMapper;

    @Autowired
    private CPaymentStatisticsMapper paymentStatisticsMapper;



    /**
     * 首页顶部数据
     *
     * @return
     */
    @ApiOperation(value="首页顶部数据", notes="首页顶部数据")
    @GetMapping(value = "/dataList")
    @RequiresPermissions(" crm:data:index")
    public Result<List<ChartCardListDTO>> dataList(@RequestParam(name="projectId",required=true) String projectId) {
        List<ChartCardListDTO> chartCardListDTOS = new ArrayList<>();
        BigDecimal taxIncludingPrice = contractMapper.sumPrice(projectId);
        BigDecimal sumMonthMPrice = contractMapper.sumMonthMPrice(projectId);
        BigDecimal totalAmount = paymentRequestMapper.getTotalAmount(projectId);//付款
        BigDecimal paymentRecordTotalAmount = paymentRecordMapper.getTotalAmount(projectId);//收款
        ChartCardListDTO chartCardListDTO = ChartCardListDTO.builder()
                .title("主合同总额")
                .icon("visit-count|svg")
                .total(taxIncludingPrice.toString())
                .value(sumMonthMPrice.toString())
                .pay(totalAmount.setScale(2, BigDecimal.ROUND_HALF_UP).toString())//付款
                .receive(paymentRecordTotalAmount.setScale(2, BigDecimal.ROUND_HALF_UP).toString())//收款
                .footer("月合同总额")
                .build();
        chartCardListDTOS.add(chartCardListDTO);


        Integer total = cSubProjectMapper.sumCount(projectId);
        Integer sumMonthCount = cSubProjectMapper.sumMonthCount(projectId);
        ChartCardListDTO chartCardListDTO2 = ChartCardListDTO.builder()
                .title("子项目量")
                .icon("total-sales|svg")
                .total(total.toString())
                .value(sumMonthCount.toString())
                .color("blue")
                .footer("月项目量")
                .build();
        chartCardListDTOS.add(chartCardListDTO2);



        BigDecimal sumMonthAmount = paymentRequestMapper.sumMonthAmount(projectId);
        ChartCardListDTO chartCardListDTO3 = ChartCardListDTO.builder()
                .title("支出总额")
                .icon("download-count|svg")
                .total(totalAmount.setScale(2, BigDecimal.ROUND_HALF_UP).toString())
                .value(sumMonthAmount.setScale(2, BigDecimal.ROUND_HALF_UP).toString())
                .color("orange")
                .footer("本月支出")
                .build();
        chartCardListDTOS.add(chartCardListDTO3);


        //收款进度
        BigDecimal contractPrice = contractMapper.contractPrice(projectId);//合同金额
        BigDecimal schedule = BigDecimal.ZERO;
        if(contractPrice.compareTo(BigDecimal.ZERO) != 0){
            schedule= (paymentRecordTotalAmount.divide(contractPrice, 4, BigDecimal.ROUND_HALF_UP)).multiply(new BigDecimal("100")).setScale(2, BigDecimal.ROUND_HALF_UP);
        }

        ChartCardListDTO chartCardListDTO4 = ChartCardListDTO.builder()
                .title("应收款进度")
                .icon("transaction|svg")
                .total(schedule.toString())
                .value(paymentRecordTotalAmount.setScale(2, BigDecimal.ROUND_HALF_UP).toString())
                .build();
        chartCardListDTOS.add(chartCardListDTO4);

        return Result.OK(chartCardListDTOS);
    }


    @ApiOperation(value="首页顶部数据-子项目数量--折线图", notes="首页顶部数据")
    @GetMapping(value = "/dataChartList")
    @RequiresPermissions(" crm:data:index")
    public Result<List<ChartDataDto>> dataChartList(@RequestParam(name="projectId",required=true) String projectId) {
        List<ChartDataDto> chart = cSubProjectMapper.getChart(projectId,6);
        List<String> lastSixMonths = DateUtils.getLastSixMonths(6);
        // 处理chart数据，确保包含所有近6个月的时间
        for (String month : lastSixMonths) {
            boolean exists = false;
            for (ChartDataDto data : chart) {
                if (data.getName().equals(month)) {
                    exists = true;
                    break;
                }
            }
            if (!exists) {
                // 如果当前月份不存在于chart中，添加一个新的ChartDataDto对象
                chart.add(new ChartDataDto(month, 0));
            }
        }
        // 按时间排序
        chart.sort(Comparator.comparing(data -> YearMonth.parse(data.getName(), DateTimeFormatter.ofPattern("yyyy-MM"))));
        return Result.OK(chart);
    }


    @ApiOperation(value="首页顶部数据-支出--折线图", notes="首页顶部数据-支出--折线图")
    @GetMapping(value = "/dataExpenditureChartList")
    @RequiresPermissions(" crm:data:index")
    public Result<List<ChartDataDto>> dataExpenditureChartList(@RequestParam(name="projectId",required=true)
                                                                   String projectId) {

        List<ChartDataDto> chart =  paymentRequestMapper.getChart(projectId);
        List<String> lastSixMonths = DateUtils.getLastSixMonths(6);
        // 处理chart数据，确保包含所有近6个月的时间
        for (String month : lastSixMonths) {
            boolean exists = false;
            for (ChartDataDto data : chart) {
                if (data.getName().equals(month)) {
                    exists = true;
                    break;
                }
            }
            if (!exists) {
                // 如果当前月份不存在于chart中，添加一个新的ChartDataDto对象
                chart.add(new ChartDataDto(month, 0));
            }
        }
        // 按时间排序
        chart.sort(Comparator.comparing(data -> YearMonth.parse(data.getName(), DateTimeFormatter.ofPattern("yyyy-MM"))));
        return Result.OK(chart);
    }


    @ApiOperation(value="首页顶部数据-第二行--柱状图", notes="首页顶部数据-第二行--柱状图")
    @GetMapping(value = "/subProjectBarData")
    @RequiresPermissions(" crm:data:index")
    public Result<List<ChartDataDto>> subProjectBarData(@RequestParam(name="projectId",required=true)
                                                               String projectId) {
        List<ChartDataDto> chart = cSubProjectMapper.getChart(projectId,12);
        List<String> lastSixMonths = DateUtils.getLastSixMonths(12);
        // 处理chart数据，确保包含所有近6个月的时间
        for (String month : lastSixMonths) {
            boolean exists = false;
            for (ChartDataDto data : chart) {
                if (data.getName().equals(month)) {
                    exists = true;
                    break;
                }
            }
            if (!exists) {
                // 如果当前月份不存在于chart中，添加一个新的ChartDataDto对象
                chart.add(new ChartDataDto(month, 0));
            }
        }
        // 按时间排序
        chart.sort(Comparator.comparing(data -> YearMonth.parse(data.getName(), DateTimeFormatter.ofPattern("yyyy-MM"))));
        return Result.OK(chart);
    }


    @ApiOperation(value="首页顶部数据-第二行--列表", notes="首页顶部数据-第二行--柱状图")
    @GetMapping(value = "/SubProjectList")
    @RequiresPermissions(" crm:data:index")
    public Result<List<IndexListDto>> SubProjectList(@RequestParam(name="projectId",required=true)
                                                        String projectId) {
        List<IndexListDto> list = cSubProjectMapper.subProjectList(projectId);
        return Result.OK(list);
    }

    @ApiOperation(value="首页顶部数据-第三行--这线图", notes="首页顶部数据-第三行--这线图")
    @GetMapping(value = "/lineMultiData")
    @RequiresPermissions(" crm:data:index")
    public Result<LineMultiDataDTO> lineMultiData(@RequestParam(name="projectId",required=true)
                                                     String projectId) {

        BigDecimal totalPayable =  paymentInvoiceMapper.totalPayable(projectId);
        BigDecimal totalTeceivables =invoiceApplyMapper.totalTeceivables(projectId);
        List<CPaymentStatistics> cPaymentStatistics = paymentStatisticsMapper.lineMultiData(projectId);
        List<Map<String,Object>> lineMultiData = new ArrayList<>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        for (CPaymentStatistics cPaymentStatistic : cPaymentStatistics) {
            Map<String,Object> map = new HashMap<>();
            map.put("name",sdf.format(cPaymentStatistic.getCreateTime()));
            map.put("type",cPaymentStatistic.getType());
            map.put("value",cPaymentStatistic.getAmount());
            map.put("color","应收".equals(cPaymentStatistic.getType())?"#1890FF":"#67B962");
            lineMultiData.add(map);
        }

        LineMultiDataDTO lineMultiDataDTO = LineMultiDataDTO.builder()
                .totalPayable(totalPayable)//应付合计 收票--并且未关联付款的
                .totalTeceivables(totalTeceivables)//应收合计 开票--并且未关联收款的
                .lineMultiData(lineMultiData)
                .build();

        return Result.OK(lineMultiDataDTO);
    }


    @ApiOperation(value="首页待处理", notes="首页待处理")
    @GetMapping(value = "/pending")
    @RequiresPermissions(" crm:data:index")
    public Result<List<PendingDTO>> pending() {
        List<PendingDTO> list = new ArrayList<>();
        PendingDTO pendingDTO = PendingDTO.builder()
                .title("项目审批")
                .count(cCommonService.executeQuery("select IFNULL(count(*),0)  from c_sub_project where status = '审核中' "))
                .url("/subproject/cSubProjectList")
                .build();
        list.add(pendingDTO);

        PendingDTO pendingDTO2 = PendingDTO.builder()
                .title("项目报价中")
                .count(cCommonService.executeQuery("select IFNULL(count(*),0)  from c_sub_project where status = '报价中' "))
                .url("/subproject/cSubProjectList")
                .build();
        list.add(pendingDTO2);

        PendingDTO pendingDTO3 = PendingDTO.builder()
                .title("付款-待审批")
                .count(cCommonService.executeQuery("select IFNULL(count(*),0)  from c_payment_request_apply where status = '待审批' "))
                .url("/paymentrequestapply/cPaymentRequestApplyList")
                .build();
        list.add(pendingDTO3);

        PendingDTO pendingDTO4 = PendingDTO.builder()
                .title("付款--待付款")
                .count(cCommonService.executeQuery("select IFNULL(count(*),0)  from c_payment_request_apply where status = '待付款' "))
                .url("/paymentrequestapply/cPaymentRequestApplyList")
                .build();
        list.add(pendingDTO4);

        PendingDTO pendingDTO5 = PendingDTO.builder()
                .title("付款--驳回")
                .count(cCommonService.executeQuery("select IFNULL(count(*),0)  from c_payment_request_apply where status = '驳回' "))
                .url("/paymentrequestapply/cPaymentRequestApplyList")
                .build();
        list.add(pendingDTO5);


        PendingDTO pendingDTO6 = PendingDTO.builder()
                .title("费用报销")
                .count(cCommonService.executeQuery("select IFNULL(count(*),0)  from c_reimbursement where audit_status = '待审核' "))
                .url("/reimbursement/cReimbursementList")
                .build();
        list.add(pendingDTO6);




        List<PendingDTO> dataList = IndexUtils.setIconAndColor(list);
        return Result.OK(dataList);
    }






}
